/****************************************************************
 *This file is NI_PXI_4064.c
 ****************************************************************/

#include "include.h"

// 函数功能明定义
#define HITMC_MODULE_INIT   				0x00050001
#define HITMC_MODULE_CLOSE					0x00050002
#define HITMC_SET_MODULE_PARA				0x00050005
#define HITMC_GET_MODULE_PARA				0x00050006
#define HITMC_DMA_SEND_FUNC					0x00050007
#define HITMC_DMA_BUFFER_LEN_FUNC			0x00050008
#define HITMC_DMA_REV_FUNC					0x00050009
#define HITMC_SET_LIST_FUNC					0x0005000A
#define HITMC_ENABLE_SELFACK_FUNC			0x0005000B
#define HITMC_SET_STORE_FILE_NAME_FUNC		0x0005000C

//server function
static void HITMC_MODULE_init(cJSON *in_data_p,  cJSON *ack_data_p);
static void HITMC_MODULE_close(cJSON *in_data_p,  cJSON *ack_data_p);
static void HITMC_SET_MODULE_para(cJSON *in_data_p,  cJSON *ack_data_p);
static void HITMC_GET_MODULE_para(cJSON *in_data_p,  cJSON *ack_data_p);
static void HITMC_DMA_SEND(cJSON *in_data_p,  cJSON *ack_data_p);
static void HITMC_DMA_BUFFER_LEN(cJSON *in_data_p,  cJSON *ack_data_p);
static void HITMC_DMA_REV(cJSON *in_data_p,  cJSON *ack_data_p);
static void HITMC_SET_LIST(cJSON *in_data_p,  cJSON *ack_data_p);
static void HITMC_Enable_Selfack(cJSON *in_data_p,  cJSON *ack_data_p);
static void HITMC_SET_STORE_FILE_name(cJSON *in_data_p,  cJSON *ack_data_p);

static void HITMC_SET_BEFORE_PROCESS(ViUInt32  RegAddr, ViUInt32  Data);

/****************************************************************
 *This function is NI PXI 4065 init function,
 *	(1)初始化4065处理函数
 ****************************************************************/
void hitmc_board_func_int(pc_cmd_str *cmd_list)
{
    unsigned int temp_i;

    // 寻找函数列表中空处理函数位置
    for(temp_i = 0; temp_i < PC_COMMAND_NUM; temp_i ++){
        if(cmd_list[temp_i].pc_command_func == 0){
            break;
        }
    }

    temp_i = 0;

    cmd_list[temp_i].pc_command_code = HITMC_MODULE_INIT;
    cmd_list[temp_i].pc_command_func = HITMC_MODULE_init;
    temp_i ++;

    cmd_list[temp_i].pc_command_code = HITMC_MODULE_CLOSE;
    cmd_list[temp_i].pc_command_func = HITMC_MODULE_close;
    temp_i ++;

    cmd_list[temp_i].pc_command_code = HITMC_SET_MODULE_PARA;
    cmd_list[temp_i].pc_command_func = HITMC_SET_MODULE_para;
    temp_i ++;

    cmd_list[temp_i].pc_command_code = HITMC_DMA_SEND_FUNC;
    cmd_list[temp_i].pc_command_func = HITMC_DMA_SEND;
    temp_i ++;

	cmd_list[temp_i].pc_command_code = HITMC_GET_MODULE_PARA;
    cmd_list[temp_i].pc_command_func = HITMC_GET_MODULE_para;
    temp_i ++;

	cmd_list[temp_i].pc_command_code = HITMC_DMA_BUFFER_LEN_FUNC;
    cmd_list[temp_i].pc_command_func = HITMC_DMA_BUFFER_LEN;
    temp_i ++;

	cmd_list[temp_i].pc_command_code = HITMC_DMA_REV_FUNC;
    cmd_list[temp_i].pc_command_func = HITMC_DMA_REV;
    temp_i ++;

	cmd_list[temp_i].pc_command_code = HITMC_SET_LIST_FUNC;
    cmd_list[temp_i].pc_command_func = HITMC_SET_LIST;
    temp_i ++;

	cmd_list[temp_i].pc_command_code = HITMC_ENABLE_SELFACK_FUNC;
    cmd_list[temp_i].pc_command_func = HITMC_Enable_Selfack;
    temp_i ++;

	cmd_list[temp_i].pc_command_code = HITMC_SET_STORE_FILE_NAME_FUNC;
    cmd_list[temp_i].pc_command_func = HITMC_SET_STORE_FILE_name;
    temp_i ++;
}

/****************************************************************
 *This function is HITMC_MODULE_init
 ****************************************************************/
static void HITMC_MODULE_init(cJSON *in_data_p,  cJSON *ack_data_p)
{
	ViStatus status = VI_ERR;
	ViBoolean IdQuery;
	ViBoolean Reset;

	// 存储获取本地时间信息
	struct timeval set_ft2000_tv;
	struct timeval get_ft2000_tv;

	// cpu的时区
	struct timezone ft2000_tz;

	ViSession 	newVi = VI_NULL;
	ViUInt32 	max_wait_data = 0;
	ViUInt32 	upload_bind_port = 0;
	ViUInt32 	load_bind_port = 0;

	//inner variable
	pthread_t pth2, pth3;
	int ret;
	unsigned int *load_port = NULL;
	unsigned int *upload_port = NULL;

	// 停止PCM码流
	dev_32bit_write(mmap_addr, 0x8, 0x65);
	usleep(10000);

	// FPGA全局复位
	dev_32bit_write(mmap_addr, 0x00, 0);
	usleep(1000);
	dev_32bit_write(mmap_addr, 0x00, 1);
	usleep(1000);

	usleep(500000);

	//get arg2
	IdQuery = (ViBoolean)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg2"));
	IdQuery = IdQuery;

	//get arg3
	Reset = (ViUInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg3"));
	Reset = Reset;

	// 获取配置时间
	set_ft2000_tv.tv_sec = (ViUInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg4"));
	set_ft2000_tv.tv_usec = (ViUInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg5"));
	//fprintf(stderr,"second is :%ld\n", set_ft2000_tv.tv_sec );
	//fprintf(stderr,"usecond is :%ld\n", set_ft2000_tv.tv_usec );
	// 调整为东8时区时间
	set_ft2000_tv.tv_sec += 28800;
	gettimeofday(&get_ft2000_tv, &ft2000_tz);
	settimeofday(&set_ft2000_tv,&ft2000_tz);

	// 开始新建日志标志置为有效
	create_log_name_flag = FLAG_VALID;

	// 开启系统监控
	start_system_monitor_flag = START_SYSTEM_MONITOR;

	// get arg1
	newVi = (ViSession)cJSON_GetNumberValue(cJSON_GetObjectItem(ack_data_p, "socketfd"));
	printf ("newVi %ld\n", newVi);

	// 调试用
	status = VI_SUCCESS;

    // 判断返回值
	if(status < VI_SUCCESS)
	{
		//printf ("An error occurred PXI5012_RS485_init to %s\n",resourceName);
	} else {
		//creat thread2
		// 申请空间，用于存储地址列表
		load_port = (unsigned int *)malloc(4);
		*load_port = HITMC_START_PORT + (unsigned int)newVi;
		ret = pthread_create(&pth2, NULL, thread2, (void *)(load_port));	
		ret = ret;

		// 等待线程建立完毕
		ack_udp_load_flag[newVi] = FLAG_INVALID;
		max_wait_data = 0;
		while(ack_udp_load_flag[newVi] == FLAG_INVALID){
			usleep(100000);
			max_wait_data ++;
			if(max_wait_data > 200){
				status = -10;
				//printf ("HITMC_MODULE_init_rpc err %d\n", status);
				break;
			}
		}
		ack_udp_load_flag[newVi] = FLAG_INVALID;
		load_bind_port = *load_port;

		// 释放内存
		free(load_port);

		//creat thread3
		// 申请空间，用于存储地址列表
		upload_port = (unsigned int *)malloc(4);
		*upload_port = HITMC_START_PORT_TWO + (unsigned int)newVi;
		ret = pthread_create(&pth3, NULL, thread3, (void *)(upload_port));	
		ret = ret;	

		// 等待线程建立完毕
		ack_udp_upload_flag[newVi] = FLAG_INVALID;
		max_wait_data = 0;
		while(ack_udp_upload_flag[newVi] == FLAG_INVALID){
			usleep(100000);
			max_wait_data ++;
			if(max_wait_data > 200){
				status = -10;
				//printf ("HITMC_MODULE_init_rpc wait err %d\n", status);
				break;
			}
		}
		ack_udp_upload_flag[newVi] = FLAG_INVALID;
		upload_bind_port = *upload_port;

		// 释放内存
		free(upload_port);
	}

    //add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg1", status);	

	//add return data2
	cJSON_AddNumberToObject(ack_data_p, "ret_arg2", newVi);	

	//add func name
	cJSON_AddStringToObject(ack_data_p, "func_name", "HITMC_MODULE_init");	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "func_num", HITMC_MODULE_INIT);	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "upload_port", upload_bind_port);	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "load_port", load_bind_port);	

	printf ("Open HITMC_MODULE_init_rpc vi: %ld, status: %ld, upload_bind_port %ld, load_bind_port %ld\n", newVi, status, upload_bind_port, load_bind_port);			
}

/****************************************************************
 *This function is HITMC_MODULE_close
 ****************************************************************/
static void HITMC_MODULE_close(cJSON *in_data_p,  cJSON *ack_data_p)
{
	ViStatus status = VI_ERR;
	ViSession vi;

	unsigned char write_to_syslog_buf[512];
	unsigned char valid_data_buf[256];

	//get arg1
    vi = (ViSession)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg1"));
	vi = vi;

	// 停止PCM码流
	dev_32bit_write(mmap_addr, 0x8, 0x65);
	usleep(10000);
	
	// FPGA全局复位
	dev_32bit_write(mmap_addr, 0x00, 0);
	usleep(1000);
	dev_32bit_write(mmap_addr, 0x00, 1);
	usleep(1000);

	// 关闭高速处理任务
	udp_socket_status[vi] = FLAG_INVALID;
	shutdown(udp_socket_fd[vi], 2);
	shutdown(udp_socket_fd_two[vi], 2);
	close(udp_socket_fd[vi]);
	close(udp_socket_fd_two[vi]);
	udp_socket_fd_two[vi] = 0;
	udp_socket_fd[vi] = 0;

	// 置返回状态值
	status = VI_SUCCESS;
	
    //add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg1", status);	

	//add func name
	cJSON_AddStringToObject(ack_data_p, "func_name", "HITMC_MODULE_close");	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "func_num", HITMC_MODULE_CLOSE);

	// 清空局部变量
	memset(write_to_syslog_buf, 0x0, sizeof(write_to_syslog_buf));	
	memset(valid_data_buf, 0x0, sizeof(valid_data_buf));		

	// 获取系统时间
	create_time_buffer(write_to_syslog_buf);

	// 生成有效信息
	sprintf((ViChar *)valid_data_buf, "%s, ret: %ld\n", "HITMC_MODULE_close", status);	

	// 将有效信息写到日志缓冲区中
	strcat((ViChar *)write_to_syslog_buf, (ViChar *)valid_data_buf);

	// 将信息发送给日志线程
	sendto(sockfd_wr_log, write_to_syslog_buf, strlen((ViChar *)write_to_syslog_buf) ,IPC_NOWAIT, \
			(struct sockaddr*)(&server_addr_wr_log), sizeof(struct sockaddr_in));					
}

/****************************************************************
 *This function is HITMC_SET_MODULE_para
 ****************************************************************/
static void HITMC_SET_MODULE_para(cJSON *in_data_p,  cJSON *ack_data_p)
{
	ViStatus status = VI_ERR;
	ViSession vi;
	ViUInt32  RegAddr;
	ViUInt32  Data;
	//unsigned short wr_data;
	unsigned int wr_data;

	unsigned char write_to_syslog_buf[512];
	unsigned char valid_data_buf[256];

	//get arg1
    vi = (ViSession)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg1"));
	vi = vi;

	//get arg2
	RegAddr = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg2"));

	//get arg3
	Data = (ViUInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg3"));

	if(RegAddr >= MMAP_SIZE){
		fprintf(stderr,"SET RegAddr is :%lx\n",RegAddr);
	}

	// 执行一些关联动作
	HITMC_SET_BEFORE_PROCESS(RegAddr, Data);

	// 参数合理后，才能进行配置
	if(RegAddr < MMAP_SIZE){
		// 进行开始存储操作
		if(RegAddr == 0xfd00){
			// 配置为开始存出
			if(Data == START_PCM_STORE){
				// 配置了存储文件，才能进行存储
				if( pcm_store_fd > 0){
					// 配置标志为开始存储
					all_store_data_len = 0;
					pcm_store_status = START_PCM_STORE;

					//fprintf(stderr,"start pcm_store_status: %x\n", pcm_store_status);


					// 置返回状态值
					status = VI_SUCCESS;
				} else {
					// 置返回状态值
					status = -50;
				}
			}

			// 配置为停止存储
			if(Data == STOP_PCM_STORE){
				if(pcm_store_fd > 0){
					// 配置标志为停止存储
					pcm_store_status = STOP_PCM_STORE;

					// 延时1s，关闭存储文件
					sleep(1);
					close(pcm_store_fd);
					pcm_store_fd = 0;

					system("sync;sync;sync");
					//fprintf(stderr,"stop pcm_store_status: %x\n", pcm_store_status);
				}

				// 置返回状态值
				status = VI_SUCCESS;
			}
		} else{
			// 配置参数
			wr_data = Data;
			dev_32bit_write(mmap_addr, RegAddr, wr_data);

			// 置返回状态值
			status = VI_SUCCESS;
		}
	} else {
		status = -1;
	}

    //add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg1", status);	

	//add func name
	cJSON_AddStringToObject(ack_data_p, "func_name", "HITMC_SET_MODULE_para");	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "func_num", HITMC_SET_MODULE_PARA);	

	// 清空局部变量
	memset(write_to_syslog_buf, 0x0, sizeof(write_to_syslog_buf));	
	memset(valid_data_buf, 0x0, sizeof(valid_data_buf));		

	// 获取系统时间
	create_time_buffer(write_to_syslog_buf);

	// 生成有效信息
	sprintf((ViChar *)valid_data_buf, "%s, date: %lx, reg: %lx, ret: %ld\n", "HITMC_SET_MODULE_para", RegAddr, Data, status);	

	// 将有效信息写到日志缓冲区中
	strcat((ViChar *)write_to_syslog_buf, (ViChar *)valid_data_buf);

	// 将信息发送给日志线程
	sendto(sockfd_wr_log, write_to_syslog_buf, strlen((ViChar *)write_to_syslog_buf) ,IPC_NOWAIT, \
			(struct sockaddr*)(&server_addr_wr_log), sizeof(struct sockaddr_in));				
}

/****************************************************************
 *This function is HITMC_GET_MODULE_para
 ****************************************************************/
static void HITMC_GET_MODULE_para(cJSON *in_data_p,  cJSON *ack_data_p)
{
	ViStatus status = VI_ERR;
	ViSession vi;
	ViUInt32  RegAddr;
	ViUInt32  Data;
	//unsigned short rd_data;
	unsigned int rd_data = 0; 

	unsigned char write_to_syslog_buf[512];
	unsigned char valid_data_buf[256];
	
	//get arg1
    vi = (ViSession)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg1"));
	vi = vi;

	//get arg2
	RegAddr = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg2"));

	if(RegAddr >= MMAP_SIZE){
		fprintf(stderr,"GET RegAddr is :%lx\n",RegAddr);
	}

	if(RegAddr < MMAP_SIZE){
		if(RegAddr == 0xfd04){

			// 填充存储状态
			Data = pcm_store_status;

		} else if(RegAddr == 0xfd08){
			 
			// 获取操作锁
			pthread_mutex_lock(&spaceMutex);

			// 填充PCM存储总空间
			Data = pcm_all_space;

			// 释放互斥锁
			pthread_mutex_unlock(&spaceMutex);

		} else if(RegAddr == 0xfd0c){
			 
			// 获取操作锁
			pthread_mutex_lock(&spaceMutex);

			// 填充PCM存储已使用空间
			Data = pcm_use_space;

			// 释放互斥锁
			pthread_mutex_unlock(&spaceMutex);

		} else if(RegAddr == 0xfd10){
			 
			// 获取操作锁
			pthread_mutex_lock(&spaceMutex);

			// 填充日志总空间
			Data = log_all_space;

			// 释放互斥锁
			pthread_mutex_unlock(&spaceMutex);

		} else if(RegAddr == 0xfd14){
			 
			// 获取操作锁
			pthread_mutex_lock(&spaceMutex);

			// 填充日志已使用空间空间
			Data = log_use_space;

			// 释放互斥锁
			pthread_mutex_unlock(&spaceMutex);
			
		} else {
			// 读取参数
			rd_data = 0;
			dev_32bit_read(mmap_addr, RegAddr, &rd_data);
			Data = rd_data;
		}

		// 置返回状态值
		status = VI_SUCCESS;
	} else {
		status = -1;
	}
	
    //add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg1", status);	

	//add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg2", Data);	

	//add func name
	cJSON_AddStringToObject(ack_data_p, "func_name", "HITMC_GET_MODULE_para");	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "func_num", HITMC_GET_MODULE_PARA);	

	// 清空局部变量
	memset(write_to_syslog_buf, 0x0, sizeof(write_to_syslog_buf));	
	memset(valid_data_buf, 0x0, sizeof(valid_data_buf));		

	// 获取系统时间
	create_time_buffer(write_to_syslog_buf);

	// 生成有效信息
	sprintf((ViChar *)valid_data_buf, "%s, date: %lx, reg: %lx, ret: %ld\n", "HITMC_GET_MODULE_para", RegAddr, Data, status);	

	// 将有效信息写到日志缓冲区中
	strcat((ViChar *)write_to_syslog_buf, (ViChar *)valid_data_buf);

	// 将信息发送给日志线程
	sendto(sockfd_wr_log, write_to_syslog_buf, strlen((ViChar *)write_to_syslog_buf) ,IPC_NOWAIT, \
			(struct sockaddr*)(&server_addr_wr_log), sizeof(struct sockaddr_in));						
}

/****************************************************************
 *This function is HITMC_DMA_SEND
 ****************************************************************/
static void HITMC_DMA_SEND(cJSON *in_data_p,  cJSON *ack_data_p)
{
	ViSession   vi;
	ViInt32  	channel;
	ViInt32  	data_len;
	ViChar	 	*data_p = NULL;
	ViStatus 	status;
	ViInt32 	temp_i = 0;
	ViInt32 	opt_place = 0;
	ViInt32		wr_len = 0;
	unsigned short wr_data = 0;

	unsigned char write_to_syslog_buf[512];
	unsigned char valid_data_buf[256];

	//get arg1
    vi = (ViSession)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg1"));

	//get arg2
    channel = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg2"));

	//get arg3
    data_len = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg3"));

	// get arg4 and write to device
	data_p = (ViChar *)malloc(data_len);

	// 置返回状态值
	status = VI_SUCCESS;

	// 成功获取到内存空间
	if(data_p != NULL){
		// 填充要接收数据的长度和缓冲区首地址
		udp_load_count[vi] = data_len;
		udp_load_data_p[vi] = data_p;

		// 置请求标志有效
		udp_load_flag[vi] = FLAG_VALID;

		// 应答应答标志
		while(ack_udp_load_flag[vi] == FLAG_INVALID){
			usleep(100);
		}
		ack_udp_load_flag[vi] = FLAG_INVALID;

		// 将数据发送给FPGA
		wr_len = data_len >> 2;
		for(temp_i = 0; temp_i < wr_len; temp_i ++){
			opt_place = temp_i << 2;
			wr_data = data_p[opt_place];
			wr_data = wr_data & 0xff;
			dev_16bit_write(mmap_addr, channel, wr_data);
		}
	} else {
		status = -1;
	}
	
	// 给出异常提示
	if (status < VI_SUCCESS)
	{
		printf ("An error occurred HITMC_DMA_SEND to %ld\n",vi);
	}

    //add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg1", status);	

	//add func name
	cJSON_AddStringToObject(ack_data_p, "func_name", "HITMC_DMA_SEND");	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "func_num", HITMC_DMA_SEND_FUNC);	

	// 释放内存空间
	free(data_p);

	// 清空局部变量
	memset(write_to_syslog_buf, 0x0, sizeof(write_to_syslog_buf));	
	memset(valid_data_buf, 0x0, sizeof(valid_data_buf));		

	// 获取系统时间
	create_time_buffer(write_to_syslog_buf);

	// 生成有效信息
	sprintf((ViChar *)valid_data_buf, "%s, channel: %ld, data_len: %ld, ret: %ld\n", "HITMC_DMA_SEND", channel, data_len, status);	

	// 将有效信息写到日志缓冲区中
	strcat((ViChar *)write_to_syslog_buf, (ViChar *)valid_data_buf);

	// 将信息发送给日志线程
	sendto(sockfd_wr_log, write_to_syslog_buf, strlen((ViChar *)write_to_syslog_buf) ,IPC_NOWAIT, \
			(struct sockaddr*)(&server_addr_wr_log), sizeof(struct sockaddr_in));
}

/****************************************************************
 *This function is HITMC_DMA_BUFFER_LEN
 ****************************************************************/
static void HITMC_DMA_BUFFER_LEN(cJSON *in_data_p,  cJSON *ack_data_p)
{
	ViSession   vi;
	ViInt32  	channel;
	ViInt32  	data_len;
	ViStatus 	status;

	unsigned char write_to_syslog_buf[512];
	unsigned char valid_data_buf[256];
	
	//get arg1
    vi = (ViSession)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg1"));
	vi = vi;

	//get arg2
	channel = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg2"));
	channel = channel;

	// 获取操作锁
	pthread_mutex_lock(&myMutex);

	// 获取指定通道的数据长度
	data_len = 0;
	data_len = pfifo_len(fifo[channel - 1]);
	data_len >>= 2;
	
	// 释放互斥锁
	pthread_mutex_unlock(&myMutex);

	// 置返回状态值
	status = VI_SUCCESS;
	
    //add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg1", status);	

	//add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg2", data_len);	

	//add func name
	cJSON_AddStringToObject(ack_data_p, "func_name", "HITMC_DMA_BUFFER_LEN");	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "func_num", HITMC_DMA_BUFFER_LEN_FUNC);	

	// 清空局部变量
	memset(write_to_syslog_buf, 0x0, sizeof(write_to_syslog_buf));	
	memset(valid_data_buf, 0x0, sizeof(valid_data_buf));		

	// 获取系统时间
	create_time_buffer(write_to_syslog_buf);

	// 生成有效信息
	sprintf((ViChar *)valid_data_buf, "%s, channel: %ld, data_len: %ld, ret: %ld\n", "HITMC_DMA_BUFFER_LEN", channel, data_len, status);	

	// 将有效信息写到日志缓冲区中
	strcat((ViChar *)write_to_syslog_buf, (ViChar *)valid_data_buf);

	// 将信息发送给日志线程
	sendto(sockfd_wr_log, write_to_syslog_buf, strlen((ViChar *)write_to_syslog_buf) ,IPC_NOWAIT, \
			(struct sockaddr*)(&server_addr_wr_log), sizeof(struct sockaddr_in));		
}

/****************************************************************
 *This function is HITMC_DMA_REV
 ****************************************************************/
static void HITMC_DMA_REV(cJSON *in_data_p,  cJSON *ack_data_p)
{
	ViSession   vi;
	ViInt32  	channel;
	ViInt32  	data_len;
	uchar	 	*data_p = NULL;
	ViStatus 	status;
	int			ret = 0;

	unsigned char write_to_syslog_buf[512];
	unsigned char valid_data_buf[256];

	//get arg1
    vi = (ViSession)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg1"));

	//get arg2
    channel = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg2"));

	//get arg3
    data_len = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg3"));

	// get arg4 and write to device
	data_p = (uchar *)malloc(data_len);

	// 置返回状态值
	status = VI_SUCCESS;

	// 内存空间申请成功，调用处理函数
	if(data_p != NULL){

		// 获取操作锁
		pthread_mutex_lock(&myMutex);

		// 将上传数据放到data_p空间中
		ret = 0;
        ret = pfifo_get(fifo[channel - 1], data_p, data_len);

		// 释放互斥锁
		pthread_mutex_unlock(&myMutex);

		// 接收upload的信息
		udp_upload_count[vi] = ret;
		udp_upload_data_p[vi] = (ViChar *)data_p;
		udp_upload_flag[vi] = FLAG_VALID;
		while(ack_udp_upload_flag[vi] == FLAG_INVALID){
			usleep(100);
		}
		ack_udp_upload_flag[vi] = FLAG_INVALID;
	} else {
		status = -1;
	}

		// 给出异常提示
	if (status < VI_SUCCESS)
	{
		printf ("An error occurred HITMC_DMA_SEND to %ld\n",vi);
	}

    //add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg1", status);	

	//add return data2
	ret /= 4;
	cJSON_AddNumberToObject(ack_data_p, "ret_arg2", ret);

	//add func name
	cJSON_AddStringToObject(ack_data_p, "func_name", "HITMC_DMA_REV");	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "func_num", HITMC_DMA_REV_FUNC);	

	// 释放内存空间
	free(data_p);

	// 清空局部变量
	memset(write_to_syslog_buf, 0x0, sizeof(write_to_syslog_buf));	
	memset(valid_data_buf, 0x0, sizeof(valid_data_buf));		

	// 获取系统时间
	create_time_buffer(write_to_syslog_buf);

	// 生成有效信息
	sprintf((ViChar *)valid_data_buf, "%s, channel: %ld, data_len: %ld, ret: %ld\n", "HITMC_DMA_REV", channel, data_len, status);	

	// 将有效信息写到日志缓冲区中
	strcat((ViChar *)write_to_syslog_buf, (ViChar *)valid_data_buf);

	// 将信息发送给日志线程
	sendto(sockfd_wr_log, write_to_syslog_buf, strlen((ViChar *)write_to_syslog_buf) ,IPC_NOWAIT, \
			(struct sockaddr*)(&server_addr_wr_log), sizeof(struct sockaddr_in));
}

/****************************************************************
 *This function is HITMC_SET_LIST
 ****************************************************************/
static void HITMC_SET_LIST(cJSON *in_data_p,  cJSON *ack_data_p)
{
	ViSession   vi;
	ViInt32 	channle_num;
	ViInt32 	list_num;
	ViInt32 	list_attr;
	ViInt32  	data_len;
	ViChar	 	*data_p = NULL;
	ViStatus 	status;
	ViInt32 	temp_i = 0;

	//get arg1
    vi = (ViSession)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg1"));

	//get arg2
    channle_num = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg2"));

	//get arg3
    list_num = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg3"));

	//get arg4
    list_attr = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg4"));

	//get arg5
    data_len = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg5"));

	// get arg4 and write to device
	data_p = (ViChar *)malloc(data_len);

	// 置返回状态值
	status = VI_SUCCESS;

	// 成功获取到内存空间
	if(data_p != NULL){
		// 填充要接收数据的长度和缓冲区首地址
		udp_load_count[vi] = data_len;
		udp_load_data_p[vi] = data_p;

		// 置请求标志有效
		udp_load_flag[vi] = FLAG_VALID;

		// 应答应答标志
		while(ack_udp_load_flag[vi] == FLAG_INVALID){
			usleep(100);
		}
		ack_udp_load_flag[vi] = FLAG_INVALID;

		// 将配置信息配置给FPGA
		channle_num = channle_num;
		list_num = list_num;
		list_attr = list_attr;
		data_len = data_len;
		temp_i = temp_i;


	} else {
		status = -1;
	}
	
	// 给出异常提示
	if (status < VI_SUCCESS)
	{
		printf ("An error occurred HITMC_DMA_SEND to %ld\n",vi);
	}

    //add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg1", status);	

	//add func name
	cJSON_AddStringToObject(ack_data_p, "func_name", "HITMC_SET_LIST");	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "func_num", HITMC_SET_LIST_FUNC);	

	// 释放内存空间
	free(data_p);
}

/****************************************************************
 *This function is HITMC_Enable_Selfack
 ****************************************************************/
static void  HITMC_Enable_Selfack(cJSON *in_data_p,  cJSON *ack_data_p)
{
	ViStatus 	status = VI_ERR;
	ViSession 	vi;
	ViInt32 	channle_num;
	ViInt32 	enable_mode;

	//get arg1
    vi = (ViSession)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg1"));
	vi = vi;

	//get arg2
	channle_num = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg2"));

	//get arg3
	enable_mode = (ViInt32)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg3"));

	// 给FPGA寄存器配置使能状态
	channle_num = channle_num;
	enable_mode = enable_mode;

	// 置返回状态值
	status = VI_SUCCESS;
	
    //add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg1", status);	

	//add func name
	cJSON_AddStringToObject(ack_data_p, "func_name", "HITMC_Enable_Selfack");	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "func_num", HITMC_ENABLE_SELFACK_FUNC);					
}

/****************************************************************
 *This function is HITMC_SET_BEFORE_PROCESS
 ****************************************************************/
static void HITMC_SET_BEFORE_PROCESS(ViUInt32  RegAddr, ViUInt32  Data)
{
	ViUInt32 temp_i, pcm_net_len;

	// 进行422复位的操作，复位16个FIFO
	if((RegAddr == 0x0) && (Data == 0x00))
	{
		for(temp_i = 0; temp_i < 16; temp_i ++){
			pfifo_reset(fifo[temp_i]);
		}
	}

	// 获取子帧长，并计算PCM长度
	if(RegAddr == 0x401c)
	{
		temp_i = Data;

		// 计算一个子帧长
		temp_i += 1;
		temp_i /= 8;
		temp_i += 8;

		// 计算PCM网络一包长度
		pcm_net_len = 0;
		pcm_net_len = (1024 / temp_i) * temp_i;

		// 按照32位，来计算一个网络包的个数
		pcm_net_len >>= 2;

		// PCM一次组播的网络包长度
		pcm_once_read_len = pcm_net_len;
		pcm_once_read_len_two = pcm_net_len;

#ifdef	TST_CODE_SWITCH
	    fprintf(stderr,"32bit once len is :%d, %d\n", \
					pcm_once_read_len, pcm_once_read_len_two);
#endif
	}
}

/****************************************************************
 *This function is HITMC_SET_STORE_FILE_name
 ****************************************************************/
static void HITMC_SET_STORE_FILE_name(cJSON *in_data_p,  cJSON *ack_data_p)
{
	ViRsrc      resourceName;
	ViSession 	vi;
	ViStatus 	status = VI_ERR;
	ViChar		full_store_name[200];

	unsigned char write_to_syslog_buf[512];
	unsigned char valid_data_buf[256];
	
	//get arg1
    vi = (ViSession)cJSON_GetNumberValue(cJSON_GetObjectItem(in_data_p, "arg1"));
	vi = vi;

	// get arg2
	resourceName = (ViRsrc)cJSON_GetStringValue(cJSON_GetObjectItem(in_data_p, "arg2"));

	// 清空缓冲区
	memset(full_store_name, 0x00, sizeof(full_store_name));

	// 填充路径
	strcat(full_store_name, "/home/root/usr_data/");

	if(strlen(full_store_name) < 100){
		// 文件名
		strcat(full_store_name, resourceName);
		//fprintf(stderr,"full_store_name: %s\n", full_store_name);
		//fprintf(stderr,"strlen(full_store_name): %d\n", strlen(full_store_name));

		// 打开PCM存储句柄
		pcm_store_fd = open(full_store_name, O_RDWR|O_CREAT, 0666);

		// 调试用
		status = VI_SUCCESS;
	} else {
		// 调试用
		status = -1;
	}

    //add return data1
	cJSON_AddNumberToObject(ack_data_p, "ret_arg1", status);	

	//add func name
	cJSON_AddStringToObject(ack_data_p, "func_name", "HITMC_SET_STORE_FILE_name");	

	//add func num
	cJSON_AddNumberToObject(ack_data_p, "func_num", HITMC_SET_STORE_FILE_NAME_FUNC);		

	// 获取系统时间
	create_time_buffer(write_to_syslog_buf);

	// 生成有效信息
	sprintf((ViChar *)valid_data_buf, "%s, pcm store name: %s, ret: %ld\n", "HITMC_SET_STORE_FILE_name", resourceName, status);	

	// 将有效信息写到日志缓冲区中
	strcat((ViChar *)write_to_syslog_buf, (ViChar *)valid_data_buf);

	// 将信息发送给日志线程
	sendto(sockfd_wr_log, write_to_syslog_buf, strlen((ViChar *)write_to_syslog_buf) ,IPC_NOWAIT, \
			(struct sockaddr*)(&server_addr_wr_log), sizeof(struct sockaddr_in));			
}

/*

	// 向自检寄存器填写测试值
	test_data = 0; 
	*(unsigned short *)(mmap_addr + 0x00) = test_data;
	dev_16bit_write(mmap_addr, 0x00, test_data);

	// 读取测试值
	test_data = 0; 
	//test_data = *(unsigned short *)(mmap_addr + 0x00);
	dev_16bit_read(mmap_addr, 0x00, &test_data);

	// 进行自检测试判断和第二次自检
	if(test_data == 0){
		// 向自检寄存器填写测试值
		test_data = 0xeb90; 
		*(unsigned short *)(mmap_addr + 0x00) = test_data;
		dev_16bit_write(mmap_addr, 0x00, test_data);

		// 读取测试值
		test_data = 0; 
		//test_data = *(unsigned short *)(mmap_addr + 0x00);
		dev_16bit_read(mmap_addr, 0x00, &test_data);

		// 自检测试通过
		if(test_data == 0xeb90){
			// 自检测试通过
			status = VI_SUCCESS;
		}
	}

*/
